# 定义一个神经网络层的函数
def nn_layer(input_tensor, input_dim, output_dim, layer_name, act=tf.nn.relu):
    # 使用tf.name_scope创建一个命名空间，方便在TensorBoard中可视化
    with tf.name_scope(layer_name):
        # 在命名空间'weights'下创建权重变量
        with tf.name_scope('weights'):
            # weight_variable函数用于创建一个权重矩阵，其形状为[input_dim, output_dim]
            weights = weight_variable([input_dim, output_dim])
        
        # 在命名空间'biases'下创建偏置变量
        with tf.name_scope('biases'):
            # bias_variable函数用于创建一个偏置向量，其形状为[output_dim]
            biases = bias_variable([output_dim])
        
        # 在命名空间'linear_compute'下计算线性激活之前的值
        with tf.name_scope('linear_compute'):
            # 计算线性部分的结果，即权重矩阵与输入张量的矩阵乘法加上偏置向量
            preactivate = tf.matmul(input_tensor, weights) + biases
        
        # 应用激活函数
        activations = act(preactivate, name='activation')
    # 返回激活后的值
    return activations

# 使用定义的nn_layer函数创建第一个隐藏层，输入维度为784，输出维度为500，命名为'layer1'
hidden1 = nn_layer(x, 784, 500, 'layer1')

# 使用tf.name_scope创建一个命名空间，用于dropout操作
with tf.name_scope('dropout'):
    # 创建一个placeholder，用于在训练和测试时传入dropout的保留概率
    keep_prob = tf.placeholder(tf.float32)
    # 应用dropout操作，降低过拟合
    dropped = tf.nn.dropout(hidden1, keep_prob)

# 使用定义的nn_layer函数创建第二个隐藏层，输入维度为500，输出维度为10，命名为'layer2'
# 这里使用tf.identity作为激活函数，即不对输出进行激活，通常用于输出层，特别是在多分类问题中
y = nn_layer(dropped, 500, 10, 'layer2', act=tf.identity)